package org.funsciencewithyourcomputer.client;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

import com.google.gwt.i18n.client.LocaleInfo;

public class Score {
	
	String name;
	String language;
	
	int score = 0;
	int bestWordScore = 0;
	String bestWord = "";

	int level = 1;

	boolean gameOver;

	long timeLevelEnd;

	float speed = 10;

	Lifecycle life;
	
	HashSet<String> userWords = new HashSet<String>();
	
	HashSet<String> hiddenWords = new HashSet<String>();
	
	Words words;
	
	public Score(Lifecycle life, Words words) {
		this.life = life;
		this.words = words;
	}

	public void add(String letters, int count) {
		userWords.add(letters);
		score += getScore(letters, count);

	}
	
	public int getScore(String letters, int count) {
		int result = this.score;
		int wordScore = getWordScore(letters);
		if (wordScore > bestWordScore) {
			bestWord = letters;
			bestWordScore = wordScore;
		}
		result += wordScore * count;
		// bonus for long words
		int length = letters.length();
		if (length == 3)
			result += 1;
		else if (length == 4)
			result += 4;
		else if (length == 5)
			result += 8;
		else if (length == 6)
			result += 16;
		else if (length == 7)
			result *= 2;
		return result - score;
	}

	public int getScore() {
		return score;
	}
	
	public int getCountLetters() {
		return words.countLetters();
	}

	public int getLevel() {
		return level;
	}

	public void increaseLevel() {
		level++;
		if (speed > 30)
			speed -= 5;
		else if (speed > 5)
			speed -= 1;
		else
			speed -= 0.3;
		if (speed < 3)
			speed = 3;
	}

	public int getSpeed() {
		return (int) speed * 1000;
	}

	public void setGameOver() {
		if (!gameOver) {
			// compute final score
			if (words.countLetters() == 0) {
				score += 50;
			} else {
				int malus = 0;
				for (String line : words.lines) {
					malus += getWordScore(line);
				}
				score -= malus;
			}
		}
		gameOver = true;
	}

	public boolean isGameOver() {
		return gameOver;
	}

	public void setTimeLevelEnd(long timeLevelEnd) {
		this.timeLevelEnd = timeLevelEnd;
	}

	public int getTimeLeft() {
		return (int) ((timeLevelEnd - System.currentTimeMillis()) / 1000);
	}

	public void pause() {
		score = 0;
	}
	
	static int[] scoreEnglish = {
		1,3,3,2,1,4,2,4,1,8,5,1,3,1,1,3,10,1,1,1,1,4,4,8,4,10
	};
	static int[] scoreFrench = {
		1,3,3,2,1,4,2,4,1,8,10,1,2,1,1,3,8,1,1,1,1,4,10,10,10,10
	};
	
	
	private int getLetterScore(char letter) {
		int index = letter - 'A';
		if (index < 0 || index > 25)
			return 0;
		return LocaleInfo.getCurrentLocale().getLocaleName().equals("fr") ? scoreFrench[index]: scoreEnglish[index];
	}
	
	public int getWordScore(String word) {
		int score = 0;
		for (char letter : word.toCharArray()) {
			score += getLetterScore(letter);
		}
		return score;
	}
	
	public String getUserWords() {
		String result = "";
		List<String> words = new ArrayList<String>(userWords);
		Collections.sort(words);
		for (String word : words)
			result += getLinkForWord(word.toLowerCase()) + " ";
		return result;
	}
	
	public String getHiddenWords() {
		String result = "";
		List<String> words = new ArrayList<String>(hiddenWords);
		Collections.sort(words);
		for (String word : words)
			result += getLinkForWord(word.toLowerCase()) + " ";
		return result;
	}
	
	public void addHiddenWord(String word) {
		hiddenWords.add(word);
	}
	
	public static String getLinkForWord(String word) {
		String url = NLS.getLanguage().equals("fr") ? "http://www.larousse.fr/dictionnaires/francais/" : "http://dictionary.reference.com/browse/";
		url += word;
		return "<a href='"+url+"' target='steg_dictionary'>"+word+"</a>";
	}
}
